#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "util.h"

// 全局常量, 字符串, 用于日志打印的标签
const static char* TAG = "mutex";

// 全局变量, 信号量
static SemaphoreHandle_t mutex = NULL;

// 写文件操作，禁止多个线程同时写入文件
void writeFile(uint8_t t)
{
    // 日志打印
    ESP_LOGI(TAG, "[task=%d]writeFile waiting", t);
    // 互斥锁
    if(xSemaphoreTake(mutex, portMAX_DELAY)) {
        // 日志打印
        ESP_LOGI(TAG, "[task=%d]writeFile start for 3 second", t);
        // 延时3s
        vTaskDelay(pdMS_TO_TICKS(3000));  
        // 日志打印  
        ESP_LOGI(TAG, "[task=%d]writeFile done, release mutex", t); 
        // 释放互斥锁
        xSemaphoreGive(mutex);
    }
}

// 高优先级任务
static void task2(void* arg)
{  
    while(1){
        // 延时1s
        vTaskDelay(pdMS_TO_TICKS(1000));
        // 写文件
        writeFile(2);
    }
}

// 中优先级任务
static void task1(void* arg)
{
    while(1){
        // 延时1s
        vTaskDelay(pdMS_TO_TICKS(1000));
        // 写文件
        writeFile(1);
    }
}

void app_main(void)
{
    //创建1个二值信号量
    mutex = xSemaphoreCreateMutex();

    //先释放信号量
    xSemaphoreGive(mutex);

    //创建1个任务，堆栈大小4096，优先级6，数值越大优先级越高
    xTaskCreate(task1, "task1", 4096, NULL, 6, NULL);

    //创建1个任务，堆栈大小4096，优先级5，数值越大优先级越高
    xTaskCreate(task2, "task2",  4096, NULL, 5,  NULL);
}